/* 
 *  <copyright file="PlayerGameService.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using SobrietyEngine.Events;
using SobrietyEngine.Events.Actor;
using SobrietyEngine.Actor;
using SobrietyEngine.Screens;
using SobrietyEngine.Guids;
using SobrietyEngine.Scene;

namespace SobrietyEngine.PlayerData
{
    public class PlayerGameService : GameComponent, IEventListener
    {

        private List<IPlayerGameData> playerInfo = new List<IPlayerGameData>();
        public List<IPlayerGameData> PlayerInfo
        {
            get { return playerInfo; }
            set { playerInfo = value; }
        }

        protected List<IPlayerGameData> waitingToSpawn = new List<IPlayerGameData>();


        protected EventRouterGameService EventRouter = null;
        protected SceneGameService SceneGameService = null;

        public PlayerGameService(Game game)
            : base(game)
        {
            game.Services.AddService(typeof(PlayerGameService), this);
        }


        public override void Initialize()
        {
            base.Initialize();
            EventRouter = (EventRouterGameService)Game.Services.GetService(typeof(IEventRouter));
            SceneGameService = (SceneGameService)Game.Services.GetService(typeof(ISceneGameService));
            RegisterEventListeners();
        }

        public virtual void RegisterEventListeners()
        {
            EventRouter.AddEventListener(typeof(ActorDied), this);
        }

        public virtual void UnregisterEventListeners()
        {
            EventRouter.RemoveEventListener(typeof(ActorDied), this);
        }


        public void KillPlayer(IPlayerGameData pi)
        {
            //this asshat died. kill 'em all.
            for (int ag = 0; ag < pi.PlayerActorGuids.Count; ag++)
            {
                IActor pa = (IActor)pi.PlayerActorGuids[ag].Resolve();
                if (pa != null)
                {
                    pa.MarkedForRemoval = true;
                }
            }

            CGuid act = CGuid.Create("Zenu", null) ;
            if (pi.PlayerActorGuids.Count > 0)
                act = pi.PlayerActorGuids[0];
            if (act != null)
                EventRouter.RaiseEvent(this, new ActorDied(act, pi.Guid));
            else
                EventRouter.RaiseEvent(this, new ActorDied(null, pi.Guid));
            pi.PlayerActorGuids.Clear();

        }

        public void RemovePlayerActors(IPlayerGameData pi)
        {
            //this asshat died. kill 'em all.
            for (int ag = 0; ag < pi.PlayerActorGuids.Count; ag++)
            {
                IActor pa = (IActor)pi.PlayerActorGuids[ag].Resolve();
                if (pa != null)
                {
                    pa.MarkedForRemoval = true;
                }
            }
            pi.PlayerActorGuids.Clear();
        }

        void IEventListener.HandleEvent(Event e)
        {
            //we check a lot of things here:
            /*
             * 1) actor died --> if a player dies, adjust stats, respawn accordingly
             * 2) player leaves --> remove them from player lsits
             * 3) playerjoins --> add them to player list
             */

            if (e.Type == typeof(ActorDied))
            {
                ActorDied aded = (ActorDied)e.Data;
                if (aded.PlayerInfoGuid != null)
                {
                    foreach (PlayerInfo pi in playerInfo)
                    {
                        if (pi.Guid.Value == aded.PlayerInfoGuid.Value)
                        {
                            RemovePlayerActors(pi);
                        }
                    }
                }
                //else -- we can check each actor in each player list...
            }

        }

    }
}